package com.myk.game.gobangchess.ai.shock;

public class Score_weighting {

    public static int score_weighting(int[][] board, int playerTurn) {
        int kernelRows = 4;
        int kernelCols = 4;
        int numRows = board.length;
        int numCols = board[0].length;
    
        int[][] boardAlt = new int[numRows][numCols];
        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < numCols; j++) {
                boardAlt[i][j] = (board[i][j] == -playerTurn) ? 2 * board[i][j] : board[i][j];
            }
        }
    
        int[][] convResult = conv2(boardAlt, kernelRows, kernelCols);
        int[][] absConvResult = abs(convResult);
        int[][] scoreMatrix1 = multiply(convResult, absConvResult);
    
        int[][] centerCheck = {
                {1, 1, 1, 1, 1, 1, 1, 1},
                {1, 2, 3, 3, 3, 3, 2, 1},
                {1, 3, 4, 5, 5, 4, 3, 1},
                {1, 3, 5, 7, 7, 5, 3, 1},
                {1, 3, 5, 7, 7, 5, 3, 1},
                {1, 3, 4, 5, 5, 4, 3, 1},
                {1, 2, 3, 3, 3, 3, 2, 1},
                {1, 1, 1, 1, 1, 1, 1, 1}
        };
    
        int[][] scoreMatrix2 = multiply(centerCheck, board);
        int scoreNearCenter = sum(scoreMatrix2);
    
        return 10 * scoreNearCenter + sum(scoreMatrix1);
    }
    
    
    private static int[][] conv2(int[][] board, int kernelRows, int kernelCols) {
        int numRows = board.length;
        int numCols = board[0].length;
        int[][] result = new int[numRows - kernelRows + 1][numCols - kernelCols + 1];
    
        for (int i = 0; i < result.length; i++) {
            for (int j = 0; j < result[0].length; j++) {
                int sum = 0;
                for (int m = 0; m < kernelRows; m++) {
                    for (int n = 0; n < kernelCols; n++) {
                        sum += board[i + m][j + n] * 1; 
                    }
                }
                result[i][j] = sum;
            }
        }
    
        return result;
    }


    private static int[][] abs(int[][] matrix) {
        int numRows = matrix.length;
        int numCols = matrix[0].length;
        int[][] result = new int[numRows][numCols];

        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < numCols; j++) {
                result[i][j] = Math.abs(matrix[i][j]);
            }
        }

        return result;
    }

    private static int[][] multiply(int[][] matrix1, int[][] matrix2) {
        int numRows = matrix1.length;
        int numCols = matrix1[0].length;
        int[][] result = new int[numRows][numCols];

        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < numCols; j++) {
                result[i][j] = matrix1[i][j] * matrix2[i][j];
            }
        }

        return result;
    }

    private static int sum(int[][] matrix) {
        int numRows = matrix.length;
        int numCols = matrix[0].length;
        int sum = 0;

        for (int i = 0; i < numRows; i++) {
            for (int j = 0; j < numCols; j++) {
                sum += matrix[i][j];
            }
        }

        return sum;
    }
}
